﻿using log4net;
using Newtonsoft.Json;
using SqlSugar;
using System.Text;

namespace PhysicalExamination5.WebApi.Utility.SqlSugar
{
    public static class SqlSugarSetup
    {

        // 获取Logger实例
        private static readonly ILog log = LogManager.GetLogger(typeof(SqlSugarSetup));

        public static void AddSqlsugarSetup(this IServiceCollection services, IConfiguration configuration,
        string dbName = "ConnectString")
        {
            SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig()
            {
                DbType = DbType.SqlServer,
                ConnectionString = configuration[dbName],
                IsAutoCloseConnection = true,
            },
                db =>
                {
                    //SQL执行事件之前。可在这里查看生成的sql  
                    db.Aop.OnLogExecuting = (sql, pars) =>
                    {
                        //开发调试使用
                        log.Debug($"{DateTime.Now.ToString("yyyyMMdd HH:mm:ss")},将要执行:Sql语句：{sql}");
                    };
                    //  调试SQL，AOP ,日志
                    db.Aop.OnLogExecuted = (sql, pars) => //SQL执行完事件
                    {
                        //获取执行后的总毫秒数
                        double sqlExecutionTotalMilliseconds = db.Ado.SqlExecutionTime.TotalMilliseconds;
                        //开发调试使用
                        log.Debug($"{DateTime.Now.ToString("yyyyMMdd HH:mm:ss")},{sql}执行完毕:执行毫秒数:{sqlExecutionTotalMilliseconds}");
                    };
                    db.Aop.OnError = (exp) =>
                    {
                        //exp.sql exp.parameters 可以拿到参数和错误Sql  
                        StringBuilder sb_SugarParameterStr = new StringBuilder("###SugarParameter参数为:");
                        var parametres = exp.Parametres as SugarParameter[];
                        if (parametres != null)
                        {
                            sb_SugarParameterStr.Append(JsonConvert.SerializeObject(parametres));
                        }

                        StringBuilder sb_error = new StringBuilder();
                        sb_error.AppendLine("SqlSugarClient执行sql异常信息:" + exp.Message);
                        sb_error.AppendLine("###赋值后sql:" + LookSQL(exp.Sql, parametres));
                        sb_error.AppendLine("###带参数的sql:" + exp.Sql);
                        sb_error.AppendLine("###参数信息:" + sb_SugarParameterStr.ToString());
                        sb_error.AppendLine("###StackTrace信息:" + exp.StackTrace);

                        //开发调试使用
                        log.Debug($"{DateTime.Now.ToString("yyyyMMdd HH:mm:ss")},执行:Sql报错信息：{sb_error}");
                    };

                    ////创建数据库 如果该库不存在，则进行创建。(这里创建的是名字为 fish 数据库)
                    //db.DbMaintenance.CreateDatabase();
                    ////初始化数据表，如果没有则创建
                    //db.CodeFirst.InitTables(typeof(UserDataTabel));


                    //技巧：拿到非ORM注入对象
                    //services.GetService<注入对象>();
                });
            services.AddSingleton<ISqlSugarClient>(sqlSugar);//这边是SqlSugarScope用AddSingleton
        }





        /// <summary>
        /// 查看赋值后的sql
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="pars">参数</param>
        /// <returns></returns>
        private static string LookSQL(string sql, SugarParameter[] pars)
        {
            if (pars == null || pars.Length == 0) return sql;

            StringBuilder sb_sql = new StringBuilder(sql);
            var tempOrderPars = pars.Where(p => p.Value != null).OrderByDescending(p => p.ParameterName.Length).ToList();//防止 @par1错误替换@par12
            for (var index = 0; index < tempOrderPars.Count; index++)
            {
                sb_sql.Replace(tempOrderPars[index].ParameterName, "'" + tempOrderPars[index].Value.ToString() + "'");
            }

            return sb_sql.ToString();
        }

    }
}
